import random
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime, timedelta

# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题


# 生成随机数据（扩展为生成多组时间序列数据）
def generate_time_series_data(days=30):
    data_series = []
    start_date = datetime.now()

    for i in range(days):
        date = start_date + timedelta(days=i)

        # 原保费收入
        original_premium_income = random.uniform(100000, 1000000)
        # 分出保费
        reinsurance_premium = random.uniform(10000, 100000)
        # 提取未到期责任准备金
        unearned_premium_reserve_extracted = random.uniform(5000, 50000)
        # 转回未到期责任准备金
        unearned_premium_reserve_reversed = random.uniform(2000, 20000)
        # 赔付支出
        claim_payment = random.uniform(50000, 500000)
        # 提取未决赔款准备金
        outstanding_claim_reserve_extracted = random.uniform(10000, 100000)
        # 转回未决赔款准备金
        outstanding_claim_reserve_reversed = random.uniform(5000, 50000)
        # 业务及管理费
        business_and_management_expenses = random.uniform(20000, 200000)
        # 手续费及佣金
        commission_and_fees = random.uniform(10000, 100000)
        # 分保费用
        reinsurance_expenses = random.uniform(5000, 50000)
        # 保险业务营业税金及附加
        insurance_business_taxes_and_surcharges = random.uniform(3000, 30000)
        # 摊回分保费用
        reinsurance_expenses_recovered = random.uniform(2000, 20000)

        data_series.append({
            'date': date,
            'original_premium_income': original_premium_income,
            'reinsurance_premium': reinsurance_premium,
            'unearned_premium_reserve_extracted': unearned_premium_reserve_extracted,
            'unearned_premium_reserve_reversed': unearned_premium_reserve_reversed,
            'claim_payment': claim_payment,
            'outstanding_claim_reserve_extracted': outstanding_claim_reserve_extracted,
            'outstanding_claim_reserve_reversed': outstanding_claim_reserve_reversed,
            'business_and_management_expenses': business_and_management_expenses,
            'commission_and_fees': commission_and_fees,
            'reinsurance_expenses': reinsurance_expenses,
            'insurance_business_taxes_and_surcharges': insurance_business_taxes_and_surcharges,
            'reinsurance_expenses_recovered': reinsurance_expenses_recovered
        })

    return data_series


# 计算已赚保费
def calculate_earned_premium(data):
    return data['original_premium_income'] - data['reinsurance_premium'] - data['unearned_premium_reserve_extracted'] + \
        data['unearned_premium_reserve_reversed']


# 计算赔付率
def calculate_loss_ratio(data):
    earned_premium = calculate_earned_premium(data)
    if earned_premium == 0:
        return 0
    return ((data['claim_payment'] + data['outstanding_claim_reserve_extracted'] - data[
        'outstanding_claim_reserve_reversed']) / earned_premium) * 100


# 计算综合费用率
def calculate_composite_expense_ratio(data):
    earned_premium = calculate_earned_premium(data)
    if earned_premium == 0:
        return 0
    return ((data['business_and_management_expenses'] + data['commission_and_fees'] + data['reinsurance_expenses'] +
             data['insurance_business_taxes_and_surcharges'] - data[
                 'reinsurance_expenses_recovered']) / earned_premium) * 100


# 计算综合成本率
def calculate_composite_cost_ratio(data):
    earned_premium = calculate_earned_premium(data)
    if earned_premium == 0:
        return 0
    numerator = (data['claim_payment'] + data['outstanding_claim_reserve_extracted'] - data[
        'outstanding_claim_reserve_reversed'] +
                 data['business_and_management_expenses'] + data['commission_and_fees'] + data['reinsurance_expenses'] +
                 data['insurance_business_taxes_and_surcharges'] - data['reinsurance_expenses_recovered'])
    return (numerator / earned_premium) * 100


# 计算保费费用率
def calculate_premium_expense_ratio(data):
    if data['original_premium_income'] == 0:
        return 0
    return (data['business_and_management_expenses'] / data['original_premium_income']) * 100


# 计算手续费及佣金比率
def calculate_commission_ratio(data):
    if data['original_premium_income'] == 0:
        return 0
    return (data['commission_and_fees'] / data['original_premium_income']) * 100


# 计算分保费用比率
def calculate_reinsurance_expense_ratio(data):
    if data['reinsurance_premium'] == 0:
        return 0
    return (data['reinsurance_expenses'] / data['reinsurance_premium']) * 100


# 绘制单个指标图表
def plot_indicator(dates, values, title, y_label, color='blue'):
    plt.figure(figsize=(10, 6))
    plt.plot(dates, values, marker='o', linestyle='-', color=color, markersize=4, linewidth=1.5)

    # 添加标题和标签
    plt.title(title, fontsize=14)
    plt.xlabel('日期', fontsize=12)
    plt.ylabel(y_label, fontsize=12)

    # 美化x轴日期显示
    plt.gcf().autofmt_xdate()
    plt.tick_params(axis='x', rotation=45)

    # 添加网格
    plt.grid(True, linestyle='--', alpha=0.7)

    # 调整布局
    plt.tight_layout()

    # 显示图表
    plt.show()




# 主函数
def main():
    # 生成30天的时间序列数据
    data_series = generate_time_series_data(days=30)
    dates = [item['date'] for item in data_series]

    # 计算各项指标的时间序列
    loss_ratios = [calculate_loss_ratio(data) for data in data_series]
    composite_expense_ratios = [calculate_composite_expense_ratio(data) for data in data_series]
    composite_cost_ratios = [calculate_composite_cost_ratio(data) for data in data_series]
    premium_expense_ratios = [calculate_premium_expense_ratio(data) for data in data_series]
    commission_ratios = [calculate_commission_ratio(data) for data in data_series]
    reinsurance_expense_ratios = [calculate_reinsurance_expense_ratio(data) for data in data_series]

    # 为每个指标绘制单独的图表
    plot_indicator(dates, loss_ratios, '赔付率变化趋势', '赔付率 (%)', 'red')
    plot_indicator(dates, composite_expense_ratios, '综合费用率变化趋势', '综合费用率 (%)', 'green')
    plot_indicator(dates, composite_cost_ratios, '综合成本率变化趋势', '综合成本率 (%)', 'purple')
    plot_indicator(dates, premium_expense_ratios, '保费费用率变化趋势', '保费费用率 (%)', 'orange')
    plot_indicator(dates, commission_ratios, '手续费及佣金比率变化趋势', '手续费及佣金比率 (%)', 'blue')
    plot_indicator(dates, reinsurance_expense_ratios, '分保费用比率变化趋势', '分保费用比率 (%)', 'brown')






if __name__ == "__main__":
    main()